using System.ComponentModel;
using System.Windows;
using FModel.Services;
using FModel.ViewModels;
using System.Windows.Controls;
using System.Linq;
using System.Collections.Specialized;

namespace FModel.Views;

public partial class AesManager
{
    private ApplicationViewModel _applicationView => ApplicationService.ApplicationView;

    public AesManager()
    {
        DataContext = _applicationView;
        InitializeComponent();

        if (_applicationView?.AesManager?.GameEntries != null)
        {
            _applicationView.AesManager.GameEntries.CollectionChanged += OnGameEntriesChanged;
        }

        SortAndFilterGameEntries();
    }

    private void OnGameEntriesChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        SortAndFilterGameEntries();
    }

    private void SortAndFilterGameEntries()
    {
        if (_applicationView?.AesManager?.GameEntries != null)
        {
            var sortedGames = _applicationView.AesManager.GameEntries
                .OrderBy(g => g.Name)
                .ToList();

            ApplyFilter(sortedGames);
        }
    }

    private void ApplyFilter(System.Collections.Generic.List<GameEntry> sortedGames)
    {
        if (_applicationView?.AesManager != null)
        {
            var filterText = GameFilterTextBox?.Text?.Trim() ?? string.Empty;

            if (string.IsNullOrEmpty(filterText))
            {
                _applicationView.AesManager.FilteredGameEntries = new System.Collections.ObjectModel.ObservableCollection<GameEntry>(sortedGames);
            }
            else
            {
                var filteredGames = sortedGames
                    .Where(g => g.Name?.Contains(filterText, System.StringComparison.OrdinalIgnoreCase) == true)
                    .ToList();
                _applicationView.AesManager.FilteredGameEntries = new System.Collections.ObjectModel.ObservableCollection<GameEntry>(filteredGames);
            }
        }
    }

    private void OnGameFilterTextChanged(object sender, TextChangedEventArgs e)
    {
        SortAndFilterGameEntries();

        if (_applicationView?.AesManager?.FilteredGameEntries != null &&
            _applicationView.AesManager.FilteredGameEntries.Count == 1)
        {
            var singleGame = _applicationView.AesManager.FilteredGameEntries.First();
            _applicationView.AesManager.SelectedGameKey = singleGame.Key;
        }
    }

    private void OnClick(object sender, RoutedEventArgs e)
    {
        Close();
    }

    private async void OnRefreshAes(object sender, RoutedEventArgs e)
    {
        await _applicationView.CUE4Parse.RefreshAes();
        await _applicationView.AesManager.InitAes();
        _applicationView.AesManager.HasChange = true;
    }

    private async void OnClosing(object sender, CancelEventArgs e)
    {
        await _applicationView.UpdateProvider(false);

        if (_applicationView?.AesManager?.GameEntries != null)
        {
            _applicationView.AesManager.GameEntries.CollectionChanged -= OnGameEntriesChanged;
        }
    }

    private void OnAddGameClick(object sender, RoutedEventArgs e)
    {
        ShowGameEditDialog(null);
    }

    private void OnEditGameClick(object sender, RoutedEventArgs e)
    {
        if (GameSelector.SelectedItem is GameEntry selectedGame)
        {
            ShowGameEditDialog(selectedGame);
        }
        else
        {
            MessageBox.Show("请先选择一个游戏", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
        }
    }

    private void ShowGameEditDialog(GameEntry gameToEdit)
    {
        var isEditing = gameToEdit != null;
        var inputWindow = new Window
        {
            Title = isEditing ? "编辑游戏" : "添加游戏",
            Width = 450,
            Height = 280,
            WindowStartupLocation = WindowStartupLocation.CenterOwner,
            Owner = this,
            ResizeMode = ResizeMode.CanResize,
            MinWidth = 400,
            MinHeight = 250,
            SizeToContent = SizeToContent.Manual,
            ToolTip = isEditing ? "编辑现有游戏的AES密钥和路径" : "添加新游戏的AES密钥和路径"
        };

        var grid = new Grid { Margin = new Thickness(20) };

        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(10) });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(10) });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(20) });
        grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

        var nameLabel = new TextBlock { Text = "游戏名称:" };
        Grid.SetRow(nameLabel, 0);

        var nameTextBox = new TextBox
        {
            MinHeight = 25,
            Text = gameToEdit?.Name ?? "",
            ToolTip = "不强制要求输入游戏原名称，为了方便你记住它，你可以输入此游戏对应的中文译名"
        };
        Grid.SetRow(nameTextBox, 1);

        var keyLabel = new TextBlock { Text = "AES密钥(仅用于单密钥游戏):" };
        Grid.SetRow(keyLabel, 3);

        var keyTextBox = new TextBox
        {
            MinHeight = 25,
            Text = gameToEdit?.Key?.Replace("0x", "") ?? "",
            ToolTip = "输入AES密钥，必须以0x开头，包含64个字符"
        };
        Grid.SetRow(keyTextBox, 4);

        var pathLabel = new TextBlock { Text = "游戏路径(可选):" };
        Grid.SetRow(pathLabel, 6);

        var pathStackPanel = new StackPanel { Orientation = Orientation.Horizontal };
        Grid.SetRow(pathStackPanel, 7);

        var pathTextBox = new TextBox
        {
            MinHeight = 25,
            MinWidth = 300,
            Text = gameToEdit?.GamePath ?? "",
            ToolTip = "选择游戏的安装目录(这个可以不输入，取决于你)"
        };
        var browseButton = new Button
        {
            Content = "浏览",
            MinWidth = 60,
            Margin = new Thickness(5, 0, 0, 0),
            ToolTip = "浏览选择游戏安装目录"
        };

        browseButton.Click += (s, e2) =>
        {
            var folderDialog = new System.Windows.Forms.FolderBrowserDialog();
            if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                pathTextBox.Text = folderDialog.SelectedPath;
            }
        };

        pathStackPanel.Children.Add(pathTextBox);
        pathStackPanel.Children.Add(browseButton);

        var okButton = new Button
        {
            Content = "确定",
            MinWidth = 80,
            MinHeight = 30,
            IsDefault = true,
            ToolTip = "点击此按钮会自动保存一个json文件到Fmodel主程序所在目录"
        };
        Grid.SetRow(okButton, 9);

        okButton.Click += (s, e2) =>
        {
            var name = nameTextBox.Text.Trim();
            var key = keyTextBox.Text.Trim();
            var path = pathTextBox.Text.Trim();

            if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(key))
            {
                if (isEditing)
                {
                    _applicationView.AesManager.UpdateGameEntry(gameToEdit, name, key, path);
                }
                else
                {
                    _applicationView.AesManager.AddGameEntry(name, key, path);
                }
                inputWindow.DialogResult = true;
            }
            else
            {
                MessageBox.Show("请输入游戏名称和AES密钥", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        };

        grid.Children.Add(nameLabel);
        grid.Children.Add(nameTextBox);
        grid.Children.Add(keyLabel);
        grid.Children.Add(keyTextBox);
        grid.Children.Add(pathLabel);
        grid.Children.Add(pathStackPanel);
        grid.Children.Add(okButton);

        inputWindow.Content = grid;

        inputWindow.Loaded += (s, e2) => nameTextBox.Focus();

        inputWindow.ShowDialog();
    }

    private void OnRemoveGameClick(object sender, RoutedEventArgs e)
    {
        if (GameSelector.SelectedItem is GameEntry selectedGame)
        {
            var result = MessageBox.Show(
                $"确定要删除游戏'{selectedGame.Name}'吗?",
                "确认删除",
                MessageBoxButton.YesNo,
                MessageBoxImage.Question);

            if (result == MessageBoxResult.Yes)
            {
                _applicationView.AesManager.RemoveGameEntry(selectedGame);
            }
        }
        else
        {
            MessageBox.Show("请先选择一个游戏", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
        }
    }
}